package com.nannybear.Communication;

import android.util.Log;

import com.nannybear.Model.Command;

import java.io.IOException;
import java.util.ArrayList;

/**
 * \brief Class which treat the reception of a message
 * \author Audrey LOISEAU
 * \date 30-03-2015
 */

/********************************* COPYRIGHT *********************************
 * Copyright (c) 2015, Audrey LOISEAU and Benjamin LANCINOT.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *************************************************************************************/

class Postman extends Thread{
    /********** DECLARATIONS **********/
    private final Connection connection;
    private final ArrayList<Command> commands = new ArrayList<>();

    /************ METHODS ************/
    /**
     * Constructor
     * \param connection    The connection
     */
    public Postman(Connection connection){
        this.connection = connection;
        this.commands.add(Protocol.TEMP_VALUE, this.connection.getActivity().getTemperatureChange());
        this.commands.add(Protocol.LIGHT_STATE, this.connection.getActivity().getBrightnessChange());
        this.commands.add(Protocol.HUM_VALUE, this.connection.getActivity().getHumidityChange());
        this.commands.add(Protocol.BABY_STATE, this.connection.getActivity().getBabyStateChange());
        this.commands.add(Protocol.HUM_THRESHOLD, this.connection.getActivity().getHumidityThresholdChange());
        this.commands.add(Protocol.TEMP_THRESHOLD, this.connection.getActivity().getTemperatureThresholdChange());
        this.commands.add(Protocol.TEMP_AVERAGE, this.connection.getActivity().getAverageTemperatureChange());
        this.commands.add(Protocol.HUM_AVERAGE, this.connection.getActivity().getAverageHumidityChange());
        this.commands.add(Protocol.LIGHT_THRESHOLD_DARK_DIM_CHANGED, this.connection.getActivity().getMultiCoLightDarkDimChanged());
        this.commands.add(Protocol.LIGHT_THRESHOLD_DIM_BRIGHT_CHANGED, this.connection.getActivity().getMultiCoLightDimBrightChanged());
        this.commands.add(Protocol.SOUND_THRESHOLD_CHANGED, this.connection.getActivity().getMultiCoSoundChanged());
        this.commands.add(Protocol.RESET_TEMP_ASKED, this.connection.getActivity().getMultiCoResetTempChanged());
        this.commands.add(Protocol.RESET_HUM_ASKED, this.connection.getActivity().getMultiCoResetHumChanged());
    }

    /**
     * \brief Decode the new message
     * \param receivedMessage   The received message
     */
    void decodeMessage(String receivedMessage){
        Log.e("Postman","msg received:"+receivedMessage);
        if(receivedMessage.length() >=3) {
            if (Character.getNumericValue(receivedMessage.charAt(0)) >= 0 && Character.getNumericValue(receivedMessage.charAt(0)) <= 12) {
                String messageStock[];
                messageStock = receivedMessage.split("/");
                if (messageStock.length == 2) {
                    try {
                        this.commands.get(Integer.parseInt(messageStock[0])).execute(messageStock[1]);
                    } catch (NumberFormatException ex) {
                        ex.getMessage();
                    }
                }
            }
        }
    }

    /**
     * \brief Thread for the reception
     */
    public void run(){
        while(connection.isConnected()){
            try{
                while(connection.getSocket().getInputStream().available() == 0){
                    Thread.sleep(10);
                }
                String receivedMessage = connection.read();
                if(receivedMessage.length()>0){
                    decodeMessage(receivedMessage);
                }
            }catch (IOException ex){
                Log.e("Postman", "Problem with the reception : "+ex.getMessage());
            }catch (InterruptedException ex){
                Log.e("Postman", "Interrupted task : "+ex.getMessage());
            }
        }
        Log.e("Postman", "Connection lost");
    }
}
